#include "main.h"
#include "usart.h"
#include "adc.h"
#include "stdio.h"
#include "tim.h"
#include "my_can.h"
#include "flash_rw.h"
#include "my_define.h"
#include "my_uart.h"
#include "uart_process.h"

//函数声明
void LightCtrl();
void BrightnessDetection();
void CanBroadcasting();
void LEDAutoControl();
void KeyScan();
FLOOR_INFO thisfloor;
//上下楼层
OTHER_STATE *next_floor;
OTHER_STATE *last_floor;
//在线信息缓冲
OTHER_STATE otherfloor[MAXFLOOR];

//用户初始化函数
void setup()
{
    for (size_t i = 0; i < MAXFLOOR; i++)
    {
        otherfloor[i].onlinecnt = 500000;
        otherfloor[i].state.InfraredDetection = 0;
    }

    thisfloor.id = 0;
    thisfloor.ref.lowlight = 900;
    thisfloor.ref.timeout = 30;
    thisfloor.state.AmbientLightLevel = 0;
    thisfloor.maxlight = 1000;
    //读取楼层信息
    if (!FLASH_FloorInfoLoad(&thisfloor.id, &thisfloor.ref.lowlight, &thisfloor.ref.timeout))
    {
        FLASH_FloorInfoSave(thisfloor.id, thisfloor.ref.lowlight, thisfloor.ref.timeout);
    }
    next_floor = &otherfloor[thisfloor.id + 1];
    last_floor = &otherfloor[thisfloor.id - 1];

    //USART初始化
    UART_IQR_INIT();

    //can初始化
    CAN_Filter_set(&hcan, &Filter, 0, 0); //接收所有帧
    CAN_StarCAN(&hcan);

    //pwm输出使能
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);

    //定时器中断使能
    HAL_TIM_Base_Start_IT(&htim3);
    HAL_TIM_Base_Start_IT(&htim4);

    LED(0);
    LED_R(10);
    LED_G(10);
}
int8_t levedir = 0;

void loop()
{
    Usartprossion();
    //亮度递增;
    switch (levedir)
    {
    case 1:
    {
        if (thisfloor.state.LightOutLevel < 1000 && thisfloor.state.LightState == ON)
        {
            thisfloor.state.LightOutLevel++;
            thisfloor.maxlight = thisfloor.state.LightOutLevel;

            HAL_Delay(10);
        }
        else
        {
            levedir = 0;
        }
    }
    break;
    case -1:
    {
        if (thisfloor.state.LightOutLevel > 1 && thisfloor.state.LightState == ON)
        {
            thisfloor.state.LightOutLevel--;
            thisfloor.maxlight = thisfloor.state.LightOutLevel;
            //printf("Leve=%d\n", thisfloor.maxlight);
            HAL_Delay(10);
        }
        else
        {
            levedir = 0;
        }
    }
    break;

    default:
        break;
    }
}

void BrightnessDetection()
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 10);
    uint32_t AD_Value = HAL_ADC_GetValue(&hadc1);
    //获取ADC转换的值
    //float Value_1 = (float)(AD_Value * 3.3 / 4096);
    double new = 4096 - AD_Value;
    double last = thisfloor.state.AmbientLightLevel;
    thisfloor.state.AmbientLightLevel = last * 0.99 + (new - last) * 0.01;
}

//所有计数向上计数
void CntUp()
{
    if (thisfloor.state.cnt < 100000)
        thisfloor.state.cnt++;
    if (thisfloor.state.ControlCnt < 100000)
        thisfloor.state.ControlCnt++;

    for (size_t i = 0; i < MAXFLOOR; i++)
    {
        if (otherfloor[i].onlinecnt < 100000)
            otherfloor[i].onlinecnt++;
    }
    if (thisfloor.Look < 250)
        thisfloor.Look++;
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == (&htim3)) //20ms主控周期
    {
        thisfloor.state.Button = KEY();
        thisfloor.state.InfraredDetection = InfraredDetection();
        BrightnessDetection();
        CanBroadcasting();
        CntUp();
        LightCtrl();
    }
    if (htim == (&htim4)) //1s次要信息周期
    {
        //printf("%dBL=%dtimes=%dlevel=%d\r\n", cnt++, AmbientLightLevel, time100ms, LightLevel);

        //GetState();
    }
}

void LightCtrl()
{

    if (thisfloor.state.ControlCnt < 50) //控制超时小于50ms才受控否则回归逻辑
    {
        thisfloor.state.LightOutLevel = thisfloor.state.ControlLevel;
        thisfloor.state.ControlState = REMOTE;
    }
    else //回归自动控制逻辑
    {
        if (thisfloor.state.ControlState == REMOTE)
            thisfloor.state.ControlState = AUTO;
    }
    KeyScan();

    switch (thisfloor.state.ControlState)
    {
    case AUTO:
    {
        //指示红外检测状态
        if (InfraredDetection() == 0)
        {
            LED_G(0);
        }
        else
        {
            LED_G(5);
        }
        LEDAutoControl();
    }
    break;
    case REMOTE:
    {
        static uint16_t Gcnt = 0;
        Gcnt++;
        if (Gcnt == 100)
        {
            LED_G(100);
        }
        if (Gcnt == 200)
        {
            Gcnt = 0;
            LED_G(0);
        }
    }
    break;
    case KEY:
    {
        LED_G(200);
    }
    break;
    default:
        break;
    }

    //指示开关灯状态
    if (thisfloor.state.LightState == ON)
    {
        LED_R(10);
    }
    else
    {
        LED_R(0);
    }
    //LED_R(thisfloor.state.LightOutLevel);
    //输出控制

    //缓开缓关动作
    if (thisfloor.state.LightState == ON)
    {
        if (thisfloor.state.LightOutLevel < thisfloor.maxlight)
        {
            thisfloor.state.LightOutLevel += 10;
        }
    }
    else
    {
        if (thisfloor.state.LightOutLevel > 0)
        {
            thisfloor.state.LightOutLevel -= 1;
        }
    }
    LED(thisfloor.state.LightOutLevel);
}
void KeyScan()
{
    static uint16_t kcnt = 0;
    if (KEY())
    {
        kcnt++;
        if (kcnt > 200)
        {
            if (thisfloor.state.LightState == ON)
            {
                if (thisfloor.dir == 0)
                {
                    if (thisfloor.state.LightOutLevel < 1000)
                    {
                        thisfloor.state.LightOutLevel++;
                        thisfloor.maxlight = thisfloor.state.LightOutLevel;
                    }
                    else
                    {
                        thisfloor.dir = 1;
                    }
                }
                else
                {
                    if (thisfloor.state.LightOutLevel > 1)
                    {
                        thisfloor.state.LightOutLevel--;
                        thisfloor.maxlight = thisfloor.state.LightOutLevel;
                    }
                    else
                    {
                        thisfloor.dir = 0;
                    }
                }
            }
        }
    }
    else
    {

        if (kcnt > 10 && kcnt < 50)
        {
            printf("key=%d\n", kcnt);
            if (thisfloor.state.ControlState != KEY)
            {
                thisfloor.state.ControlState = KEY;
                thisfloor.state.LightState = ON;
            }
            else
            {
                thisfloor.state.ControlState = AUTO;
            }
        }
        if (kcnt > 200)
        {
            if (thisfloor.dir)
            {
                thisfloor.dir = 0;
            }
            else
            {
                thisfloor.dir = 1;
            }
        }
        kcnt = 0;
    }
}
void BlueTooth(uint8_t *data)
{
    //printf("blue tooth\n");
    switch (data[0])
    {
    case 0x00: //开
    {
        if (thisfloor.state.ControlState != KEY)
        {
            thisfloor.state.ControlState = KEY;
            thisfloor.state.LightState = ON;
            printf("light on\n");
        }
    }
    break;
    case 0x01: //关
    {
        thisfloor.state.ControlState = AUTO;
        printf("light off\n");
    }
    break;
    case 0x03: //增加亮度
    {
        if (thisfloor.state.LightState == ON)
            levedir = 1;
    }
    break;
    case 0x04: //增加亮度
    {
        if (thisfloor.state.LightState == ON)
            levedir = -1;
    }
    break;
    case 0x05: //停止亮度变化
    {
        levedir = 0;
        printf("Leve=%d\n", thisfloor.maxlight);
    }
    break;
    case 0x06: //设定亮度
    {
        if (thisfloor.state.LightState == ON)
        {
            uint16_t level = *(uint16_t *)&data[1];
            if (level > 0 && level <= 1000)
            {
                thisfloor.state.LightOutLevel = level;
                thisfloor.maxlight = thisfloor.state.LightOutLevel;
                printf("set level =%d\n", thisfloor.maxlight);
            }
        }
    }
    break;
    case 0x07: //读取信息
    {
        printf("BL=%d low=%d LED=%d\n", thisfloor.state.AmbientLightLevel, thisfloor.ref.lowlight, thisfloor.state.LightOutLevel);
    }
    break;
    case 0x08: //增加阈值
    {
        thisfloor.ref.lowlight += 2;
        FLASH_FloorInfoSave(thisfloor.id, thisfloor.ref.lowlight, thisfloor.ref.timeout);
        printf("low=%d\n", thisfloor.ref.lowlight);
    }
    break;
    case 0x09: //减少阈值
    {
        thisfloor.ref.lowlight -= 2;
        FLASH_FloorInfoSave(thisfloor.id, thisfloor.ref.lowlight, thisfloor.ref.timeout);
        printf("low=%d\n", thisfloor.ref.lowlight);
    }
    break;

    default:
        break;
    }
}
//自动控制
void LEDAutoControl()
{
    //开灯逻辑,本楼层有人或者上下层有人
    if (thisfloor.state.InfraredDetection || (next_floor->onlinecnt < 50 && next_floor->state.InfraredDetection) || (last_floor->onlinecnt < 50 && last_floor->state.InfraredDetection))
    {
        thisfloor.state.cnt = 0;
        if (thisfloor.state.AmbientLightLevel < thisfloor.ref.lowlight || thisfloor.state.LightOutLevel > 0) //亮度小于阈值，或者正在亮着还未全灭
        {
            thisfloor.state.LightState = ON; //红外有人就打开
        }
    }

    //关灯逻辑
    if (thisfloor.state.cnt > thisfloor.ref.timeout * 100)
    {
        thisfloor.state.LightState = OFF;
    }
}

//修改id,第一次解锁第二次设置
void ChangeID(uint8_t newid)
{
    printf("change id %d\n", thisfloor.Look);

    if (thisfloor.Look > 50)
    {
        thisfloor.Look = 0;
        return;
    }
    if (newid == thisfloor.id)
        return;
    if (newid > MAXFLOOR)
        return;
    printf("change id ok\n");
    thisfloor.id = newid;
    next_floor = &otherfloor[thisfloor.id + 1];
    last_floor = &otherfloor[thisfloor.id - 1];
    FLASH_FloorInfoSave(thisfloor.id, thisfloor.ref.lowlight, thisfloor.ref.timeout);
}